package cn.laixueit.service.impl;

import cn.laixueit.CacheKey;
import cn.laixueit.crawlerutil.CrawlerUtil;
import cn.laixueit.mapper.BookMapper;
import cn.laixueit.pojo.Book;
import cn.laixueit.service.BookService;
import com.fasterxml.jackson.databind.ser.std.ObjectArraySerializer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
@Transactional
public class BookServiceImpl implements BookService {

    @Autowired
    private BookMapper bookMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    public List<Book> findAll(String bookName){
        List<Book> redisbookList = redisTemplate.boundHashOps(CacheKey.BOOK).values();
        if(redisbookList.size()==0 || redisbookList == null){
            Example example = new Example(Book.class);
            Example.Criteria criteria = example.createCriteria();
            if(bookName!=null && !"".equals(bookName)){
                criteria.andEqualTo("bookName",bookName);
            }
            List<Book> dbBookList = bookMapper.selectByExample(example);
            if (dbBookList.size()==0 || dbBookList==null){ // 数据库没有
                // 都没有就爬取
                List<Map> crawBookList = CrawlerUtil.getBookName(CrawlerUtil.BIQUGE_URL);
                add(crawBookList); //爬完存数据库
                dbBookList = bookMapper.selectByExample(example);
            }
            // 存redis
            for (Book book : dbBookList) {
                redisTemplate.boundHashOps(CacheKey.BOOK).put(book.getId(),book);
            }
            return dbBookList;
        }
        if(bookName!=null && !"".equals(bookName)){
            List<Book> list = getBooksByName(redisbookList, bookName);
            return list;
        }
        return redisbookList;
    }

    private List<Book> getBooksByName(List<Book> bookList,String bookName){
        List<Book> books = new ArrayList<>();
        for (Book book : bookList) {
            if(book.getBookName().indexOf(bookName)!=-1){
                books.add(book);
            }
        }
        return books;
    }

    @Override
    public void add(List<Map> mapList) {
        Example example = new Example(Book.class);

        List<Book> bookList = bookMapper.selectByExample(example);
        if(mapList.size()!=bookList.size()){
            for (Map map : mapList) {
                Book book = new Book();
                String name = isBookName(bookList, (String) map.get("bookName"));
                if(name!=null){
                    book.setBookName(name);
                    book.setLinkUrl((String) map.get("linkUrl"));

                    bookMapper.insertSelective(book);
                }
            }
        }
    }

    private String isBookName(List<Book> bookList,String bookName){

//        List<String> bookNameList = new ArrayList<>();
        if(bookList.size()==0){
            return bookName;
        }
        for (Book book : bookList) {
            if(book.getBookName().equals(bookName)){
                return null;
            }
        }
        return bookName;

    }

    // 查询
    public Book findByBookId(Integer bookId) {
//        Example example = new Example(Book.class);
//        example.createCriteria().andEqualTo("id",bookId);
//        List<Book> books = bookMapper.selectByExample(example);
//        return books.get(0);
         Book book = (Book) redisTemplate.boundHashOps(CacheKey.BOOK).get(bookId);
         return book;
    }

    @Override
    public Book findByDBBookId(Integer bookId) {
        Example example = new Example(Book.class);
        example.createCriteria().andEqualTo("id",bookId);
        List<Book> books = bookMapper.selectByExample(example);
        return books.get(0);
    }

    // 缓存所有书名到记录中
    public void cache() {
        redisTemplate.delete(CacheKey.BOOK);
        List<Book> bookList = bookMapper.selectAll();
        for (Book book : bookList) {
            redisTemplate.boundHashOps(CacheKey.BOOK).put(book.getId(),book);
        }
    }
}
